/**
 * 
 */
package com.netflexitysolutions.amazonws.sdb;

import java.util.Iterator;
import java.util.List;

import com.amazonaws.sdb.doc._2009_04_15.AmazonSDBPortType;
import com.netflexitysolutions.amazonws.sdb.internal.iterators.DomainListIterator;
import com.netflexitysolutions.amazonws.sdb.internal.iterators.SelectItemListIterator;
import com.netflexitysolutions.amazonws.sdb.internal.operations.BatchPutAttributesOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.CreateDomainOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.DeleteAttributesOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.DeleteDomainOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.GetAttributesOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.GetDomainMetadataOperation;
import com.netflexitysolutions.amazonws.sdb.internal.operations.PutAttributesOperation;

/**
 * @author netflexity
 *
 */
public class SimpleDBClient implements SimpleDB {
	
	private AmazonSDBPortType service;

	/**
	 * @param service
	 */
	public SimpleDBClient(AmazonSDBPortType service) {
		this.service = service;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#createDomain(java.lang.String)
	 */
	public Domain createDomain(String domainName) throws SimpleDBException{
		return createDomain(domainName, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#createDomain(java.lang.String, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public Domain createDomain(String domainName, ResponseCallback callback) throws SimpleDBException{
		CreateDomainOperation operation = new CreateDomainOperation(this, domainName);
		Domain domain = operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
		return domain;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#deleteDomain(com.netflexitysolutions.amazonws.sdb.Domain)
	 */
	public void deleteDomain(Domain domain) throws SimpleDBException{
		deleteDomain(domain, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#deleteDomain(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public void deleteDomain(Domain domain, ResponseCallback callback) throws SimpleDBException{
		DeleteDomainOperation operation = new DeleteDomainOperation(this, domain);
		operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getDomains(com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public Iterator<List<Domain>> getDomains(ResponseCallback callback) throws SimpleDBException{
		assert(callback != null);
		DomainListIterator iterator = new DomainListIterator(this, callback);
		iterator.init();
		return iterator;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getDomains()
	 */
	public Iterator<List<Domain>> getDomains() throws SimpleDBException{
		return getDomains(new DefaultResponseCallback(ResponseCallback.MAX_NUMBER_OF_DOMAINS));
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#select(java.lang.String, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public Iterator<List<Item>> select(String query, ResponseCallback callback) throws SimpleDBException{
		assert(callback != null);
		SelectItemListIterator iterator = new SelectItemListIterator(this, callback, query);
		iterator.init();
		return iterator;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#select(java.lang.String)
	 */
	public Iterator<List<Item>> select(String query) throws SimpleDBException{
		return select(query, new DefaultResponseCallback(ResponseCallback.MAX_NUMBER_OF_SELECTED_ITEMS));
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public Item getItem(Domain domain, Item item, ResponseCallback callback) throws SimpleDBException{
		GetAttributesOperation operation = new GetAttributesOperation(this, domain, item);
		Item foundItem = operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
		return foundItem;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item)
	 */
	public Item getItem(Domain domain, Item item) throws SimpleDBException{
		return getItem(domain, item, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#addOrUpdateItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public void addOrUpdateItem(Domain domain, Item item, ResponseCallback callback) throws SimpleDBException{
		PutAttributesOperation operation = new PutAttributesOperation(this, domain, item);
		operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#addOrUpdateItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item)
	 */
	public void addOrUpdateItem(Domain domain, Item item) throws SimpleDBException{
		addOrUpdateItem(domain, item, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#addOrUpdateItems(com.netflexitysolutions.amazonws.sdb.Domain, java.util.List, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public void addOrUpdateItems(Domain domain, List<Item> items, ResponseCallback callback) throws SimpleDBException{
		BatchPutAttributesOperation operation = new BatchPutAttributesOperation(this, domain, items);
		operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#deleteItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public void deleteItem(Domain domain, Item item, ResponseCallback callback) throws SimpleDBException{
		DeleteAttributesOperation operation = new DeleteAttributesOperation(this, domain, item);
		operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#deleteItem(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.Item)
	 */
	public void deleteItem(Domain domain, Item item) throws SimpleDBException{
		deleteItem(domain, item, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getDomainMetadata(com.netflexitysolutions.amazonws.sdb.Domain, com.netflexitysolutions.amazonws.sdb.ResponseCallback)
	 */
	public DomainMetadata getDomainMetadata(Domain domain, ResponseCallback callback) throws SimpleDBException{
		GetDomainMetadataOperation operation = new GetDomainMetadataOperation(this, domain);
		DomainMetadata metadata = operation.execute();
		if(callback != null){
			callback.onResponse(operation.getStats());
		}
		return metadata;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getDomainMetadata(com.netflexitysolutions.amazonws.sdb.Domain)
	 */
	public DomainMetadata getDomainMetadata(Domain domain) throws SimpleDBException{
		return getDomainMetadata(domain, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#addOrUpdateItems(com.netflexitysolutions.amazonws.sdb.Domain, java.util.List)
	 */
	public void addOrUpdateItems(Domain domain, List<Item> items) throws SimpleDBException{
		addOrUpdateItems(domain, items, null);
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.SimpleDB#getService()
	 */
	public AmazonSDBPortType getService() {
		return service;
	}

	/**
	 * @param service the service to set
	 */
	public void setService(AmazonSDBPortType service) {
		this.service = service;
	}
}
